// Xampler, a MIDI-driven sampler
// Copyright (C) 2006 Nick Thomas
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
// 02110-1301 USA.

#include "InstrumentEditor.hpp"
#include <gtkmm/stock.h>
using namespace xampler;

InstrumentEditor::InstrumentEditor()
    : m_button_box(Gtk::BUTTONBOX_START),
      m_button_add_sample(Gtk::Stock::ADD)
{
    m_current_instrument = -1;

    for (int i = 0; i < MAX_INSTRUMENTS; i++) {
        for (int j = 0; j < MAX_SAMPLES; j++) {
            m_sample_strips[i][j] = 0;
        }
    }

    for (int i = 0; i < MAX_INSTRUMENTS; i++) {
        Glib::ustring name = g_state->get_instrument(i).get_name();
        m_notebook.append_page(m_instrument_panes[i], name, name);
    }

    m_notebook.set_scrollable(true);
    m_notebook.signal_switch_page().connect(
        sigc::mem_fun(*this, &InstrumentEditor::on_notebook_switch_page));

    m_instrument_name_entry.signal_changed().connect(
        sigc::mem_fun(*this, &InstrumentEditor::on_name_entry_changed));

    m_button_box.pack_end(m_button_add_sample);

    pack_end(m_button_box, Gtk::PACK_SHRINK);
    pack_end(m_instrument_name_entry, Gtk::PACK_SHRINK);
    pack_end(m_notebook, Gtk::PACK_EXPAND_WIDGET);
}

void InstrumentEditor::set_current_instrument(int current_instrument)
{
    m_notebook.set_current_page(m_current_instrument);
}

void InstrumentEditor::handle_synth_message(SynthMessage &msg)
{
    SampleStrip *strip;

    switch (msg.type) {
    case SYNTH_MSG_SAMPLE_ON:
        strip = m_sample_strips
            [msg.sample_on.instrument][msg.sample_on.sample];
        if (strip) {
            strip->increment_playing_count();
        }
        break;
    case SYNTH_MSG_SAMPLE_OFF:
        strip = m_sample_strips
            [msg.sample_off.instrument][msg.sample_off.sample];
        if (strip) {
            strip->decrement_playing_count();
        }
        break;
    }
}

void InstrumentEditor::rescan_samples()
{
    // Remove all samples.
    for (int i = 0; i < MAX_INSTRUMENTS; i++) {
        for (int j = 0; j < MAX_SAMPLES; j++) {
            remove_sample(i, j);
        }
    }

    // Add all samples.
    Glib::ustring ignore;

    for (int i = 0; i < MAX_INSTRUMENTS; i++) {
        Instrument &instrument = g_state->get_instrument(i);

        for (int j = 0; j < MAX_SAMPLES; j++) {
            if (instrument.get_sample(j)) {
                // XXX: Remove testing code.
                printf("%i,%i\n", i, j);
                if (!add_sample(i, j, ignore)) {
                    printf("%s, %i, %i\n", ignore.c_str(), i, j);
                }
            }
        }

        m_instrument_panes[i].show_all_children();
    }

    // Load in the instrument names.
    for (int i = 0; i < MAX_INSTRUMENTS; i++) {
        Glib::ustring name = g_state->get_instrument(i).get_name();
        m_notebook.set_tab_label_text(m_instrument_panes[i], name);
    }

    m_instrument_name_entry.set_text
        (g_state->get_instrument(m_current_instrument).get_name());
}

bool InstrumentEditor::add_sample(int instrument, int sample,
                                  Glib::ustring &error)
{
    if (m_sample_strips[instrument][sample]) {
        error = "there is already a sample with that number";
        return false;
    } else {
        SampleStrip *strip = Gtk::manage(new SampleStrip);
        strip->set_sample(instrument, sample);
        m_sample_strips[instrument][sample] = strip;
        m_instrument_panes[instrument].add_sample_strip(strip);
        return true;
    }
}

void InstrumentEditor::remove_sample(int instrument, int sample)
{
    // XXX: We need to remove the old sample strips from the
     // instrument panes.
    if (m_sample_strips[instrument][sample]) {
        delete m_sample_strips[instrument][sample];
        m_sample_strips[instrument][sample] = 0;
    }
}

void InstrumentEditor::on_name_entry_changed()
{
    Glib::ustring name = m_instrument_name_entry.get_text();
    g_state->get_instrument(m_current_instrument).set_name(name);
    m_notebook.set_tab_label_text(m_instrument_panes[m_current_instrument],
                                  name);
}

void InstrumentEditor::on_notebook_switch_page(GtkNotebookPage *page,
                                               guint page_num)
{
    m_current_instrument = page_num;
    m_instrument_name_entry.
        set_text(g_state->get_instrument(m_current_instrument).get_name());
    m_instrument_panes[m_current_instrument].show_all_children();
}

InstrumentPane::InstrumentPane()
{
    set_shadow_type(Gtk::SHADOW_NONE);
    set_policy(Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC);
    add(m_sample_list);
}

void InstrumentPane::add_sample_strip(SampleStrip *strip)
{
    m_sample_list.pack_end(*strip, Gtk::PACK_SHRINK);
}
